/*
 *	Source: http://www.yolinux.com/TUTORIALS/XML-Xerces-C.html
 */

#include <string>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <list>


#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>

#include "XMLParser.h"



using namespace xercesc;
using namespace std;



/**
 *  - Tests the access and availability of the XML configuration file.
 *  - Configures the xerces-c DOM parser.
 *  - Reads and extracts the pertinent information from the XML config file.
 * @param const char * configFile - filename
 * @param Player* const player - player information is stored here
 * @return void
 */
void XMLParser::readPlayerConfigFile(const char * configFile, Player* const player)
{
	try
	{
		if (checkFile(configFile) == -1)
		{
			throw(std::runtime_error( "XML document not available" ));
		}
		m_ConfigFileParser->parse( configFile );
		DOMDocument* xmlDoc = m_ConfigFileParser->getDocument();
		DOMElement* elementRoot = xmlDoc->getDocumentElement();
		if( !elementRoot )
		{
			throw(std::runtime_error( "empty XML document" ));
		}
		if (!XMLString::equals(elementRoot->getTagName(), m_TAG_root))
		{
			throw(std::runtime_error( "Bad root tag for this config file." ));
		}
		DOMNodeList* childrens = elementRoot->getElementsByTagName(m_TAG_ApplicationSettings);
		const  XMLSize_t nodeCount = childrens->getLength();
		for( XMLSize_t i = 0; i < nodeCount; ++i )
		{
			DOMElement* currentElement = dynamic_cast< xercesc::DOMElement* >(childrens->item(i));
			if (m_ATTR_Options.size() == XMLPARSER_NUMOPTIONS_PLAYERCONFIG)
			{
				player->setName(XMLString::transcode(currentElement->getAttribute(m_ATTR_Options[0])));
				player->setHP(atoi(XMLString::transcode(currentElement->getAttribute(m_ATTR_Options[1]))),
							 atoi(XMLString::transcode(currentElement->getAttribute(m_ATTR_Options[2]))));
				player->setMP(atoi(XMLString::transcode(currentElement->getAttribute(m_ATTR_Options[3]))),
							 atoi(XMLString::transcode(currentElement->getAttribute(m_ATTR_Options[4]))));
				player->setXP(atoi(XMLString::transcode(currentElement->getAttribute(m_ATTR_Options[5]))),
							 atoi(XMLString::transcode(currentElement->getAttribute(m_ATTR_Options[6]))));
				player->setLevel(atoi(XMLString::transcode(currentElement->getAttribute(m_ATTR_Options[7]))));
				player->setGold(atoi(XMLString::transcode(currentElement->getAttribute(m_ATTR_Options[8]))));
				player->setPhysicalCombatAttr(atoi(XMLString::transcode(currentElement->getAttribute(m_ATTR_Options[9]))),
							 atoi(XMLString::transcode(currentElement->getAttribute(m_ATTR_Options[10]))));
				player->setMagicalCombatAttr(atoi(XMLString::transcode(currentElement->getAttribute(m_ATTR_Options[11]))),
							 atoi(XMLString::transcode(currentElement->getAttribute(m_ATTR_Options[12]))));
				player->setEvasion(atoi(XMLString::transcode(currentElement->getAttribute(m_ATTR_Options[13]))));
				player->setDiscretion(atoi(XMLString::transcode(currentElement->getAttribute(m_ATTR_Options[14]))),
							 atoi(XMLString::transcode(currentElement->getAttribute(m_ATTR_Options[15]))));
				player->setAttributes(atoi(XMLString::transcode(currentElement->getAttribute(m_ATTR_Options[16]))),
							 atoi(XMLString::transcode(currentElement->getAttribute(m_ATTR_Options[17]))),
							 atoi(XMLString::transcode(currentElement->getAttribute(m_ATTR_Options[18]))),
							 atoi(XMLString::transcode(currentElement->getAttribute(m_ATTR_Options[19]))),
							 atoi(XMLString::transcode(currentElement->getAttribute(m_ATTR_Options[20]))));
			}
		}
	}
	catch( xercesc::XMLException& e )
	{
		char* message = xercesc::XMLString::transcode( e.getMessage() );
		ostringstream errBuf;
		errBuf << "Error parsing file: " << message << flush;
		XMLString::release( &message );
	}
}

/**
 *  - Tests the access and availability of the XML configuration file.
 *  - Configures the xerces-c DOM parser.
 *  - Reads and extracts the pertinent information from the XML config file.
 * @param const char * configFile - filename
 * @param std::string& strClassName - class information is stored here
 * @return void
 */
void XMLParser::readClassFromPlayerConfigFile(const char * configFile, std::string& strClassName)
{
	try
	{
		if (checkFile(configFile) == -1)
		{
			throw(std::runtime_error( "XML document not available" ));
		}
		m_ConfigFileParser->parse( configFile );
		DOMDocument* xmlDoc = m_ConfigFileParser->getDocument();
		DOMElement* elementRoot = xmlDoc->getDocumentElement();
		if( !elementRoot )
		{
			throw(std::runtime_error( "empty XML document" ));
		}
		if (!XMLString::equals(elementRoot->getTagName(), m_TAG_root))
		{
			throw(std::runtime_error( "Bad root tag for this config file." ));
		}
		DOMNodeList* childrens = elementRoot->getElementsByTagName(m_TAG_ApplicationSettings);
		const  XMLSize_t nodeCount = childrens->getLength();
		for( XMLSize_t i = 0; i < nodeCount; ++i )
		{
			DOMElement* currentElement = dynamic_cast< xercesc::DOMElement* >(childrens->item(i));
			if (m_ATTR_Options.size() == XMLPARSER_NUMOPTIONS_PLAYERCONFIG)
			{
				strClassName = XMLString::transcode(currentElement->getAttribute(m_ATTR_Options[21]));
			}
		}
	}
	catch( xercesc::XMLException& e )
	{
		char* message = xercesc::XMLString::transcode( e.getMessage() );
		ostringstream errBuf;
		errBuf << "Error parsing file: " << message << flush;
		XMLString::release( &message );
	}
}